// transactions.cpp
// Customizer_Base
// Protea Customizer/Customizer Pro / Business Logic for managing transactions
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Please send correspondence to:
//
// theproteaproject@gmail.com
//

#include "base_setup.h"

// Transaction Subtransactions
//
//////////////////////////////////////////////////////////////////////////////

//@ SEC 3
//@ CHA TransactionVerify
//@ COD TransactionVerify
//@ GEN Use TransactionVerify to verify a transaction record

void TransactionVerify( XCBuffer* input, verify_type verify_mode, XCTransactionVars* vars ) {
	TRANS_INFUNC( TransactionVerify );

	XCField* temp = input->GetField( FLD_TRANS_CODE );

	if (temp) {
		//@ SUB ValidateName to check for a valid name
		ValidateName( FLD_TRANS_CODE, vars->buffer, ERR_TRANSACTION, vars );
	};

	//@ If verifying an ADD transaction,
	if (verify_mode == VERIFY_ADD) {
		//@ GRS

		//@ Verify that a transaction with the same name does not already exist
		//@ UTL LookupNumberFromName to convert trans name into a trans number
		//@ ERR C (ALREADY_EXISTS) Transaction already exists
		if ( LookupNumberFromName( vars, vars->buffer, input, FLD_TRANS_NUMBER, FLD_TRANS_CODE, FMT_TRANSACTION_DEFN ) )
			vars->Errors->Add( ERR_ALREADY_EXISTS, SEV_CRITICAL, FLD_TRANS_CODE, 1, ERR_TRANSACTION );

		// TODO: Fix use new transaction number
		input->GetField( FLD_TRANS_NUMBER )->SetLong( 4 );
	
		//@ GRE
	} else { // Review, Change or delete
		//@ GRS

		//@ If transaction number is not supplied,
		XCField* trans_number = vars->buffer->GetField( FLD_TRANS_NUMBER );
		if (!trans_number || trans_number->IsBlank()) {
			//@ GRS

			//@ UTL LookupNumberFromName
			if (!LookupNumberFromName( vars, vars->buffer, input, FLD_TRANS_NUMBER, FLD_TRANS_CODE, FMT_TRANSACTION_DEFN ))
				vars->Errors->Add( ERR_DOESNT_EXIST, SEV_CRITICAL, FLD_TRANS_CODE, 1, ERR_TRANSACTION );

			//@ GRE
		};

		//@ Verify that the transaction does exist, if not:
		//@ ERR E (DOESNT_EXIST) Transaction doesn't exist
		if (!TransactionRetrieve( input, vars ))
			vars->Errors->Add( ERR_DOESNT_EXIST, SEV_CRITICAL, FLD_TRANS_CODE, 1, ERR_TRANSACTION );

		//@ GRE
	};

	TRANS_OUTFUNC();
};


//@ SEC 3
//@ CHA TransactionRetrieve
//@ COD TransactionRetrieve
//@ GEN Use TransactionVerify to retrieve a transaction record

bool TransactionRetrieve( XCBuffer* buf, XCTransactionVars* vars ) 
{
	TRANS_INFUNC( TransactionRetrieve );

	bool result = false;
	XCDBStatement* stmt = NULL;
	XCSQLGen* query = vars->query;

	try {
		XCCompare comptemp;
		query->MakeSELECT( buf );
		query->AddWHERE( 2, buf->GetField( FLD_TRANS_NUMBER ), buf->GetField( FLD_APPL_NBR ) );
		stmt = vars->dbtxn->ExecuteSQL( query );
		result = (!stmt->Eof());
	} catch( ... ) {
		App->CleanupObjects( 1, &stmt );
		throw;
	};
	App->CleanupObjects( 1, &stmt );

	TRANS_OUTFUNCRET( result );
};


//@ SEC 3
//@ CHA TransactionChange
//@ COD TransactionChange
//@ GEN Use TransactionChange to alter a transaction record

void TransactionChange( XCBuffer* buf, XCBuffer* orig, XCTransactionVars* vars ) 
{
	TRANS_INFUNC( TransactionChange );

	XCSQLGen* query = vars->query;
	query->MakeFull( SQL_STMT_UPDATE, buf, orig );
	vars->dbtxn->ExecuteSQL( query, SQL_NO_RESULT );

	TRANS_OUTFUNC();
};



//@ SEC 3
//@ CHA Transaction Delete All
//@ COD TransactionDeleteAll
//@ TAB TRANSACTION_DEFN Write
//@ GEN Use to delete all transaction definition records
void TransactionDeleteAll( XCBuffer* buf, XCTransactionVars* vars ) 
{
	TRANS_INFUNC( TransactionDeleteAll );

	XCCompare comp[2];
	XCField* flist[2];
	XCSQLGen* query = vars->query;
	XCBuffer* lits = App->CreateBuffer( FMT_TRANSACTION_DEFN, false );
	lits->MoveField( buf, FLD_APPL_NBR );

	//@ Delete the literal definition record
	query->MakeDELETE( lits );

	flist[0] = lits->GetField( FLD_APPL_NBR );
	flist[1] = NULL;
	query->AddWHERE( flist, comp );

	vars->dbtxn->ExecuteSQL( query, SQL_NO_RESULT );

	lits->Release();

	TRANS_OUTFUNC();
};
